【打卡贴】(No.001)从零开始刷LeetCode
点击上方“Ahab杂货铺”,选择“置顶公众号”
技术分享第一时间送达!
写在前面:
打卡刷LeetCode是受小詹的启发,自己也会在LeetCode刷题之前只是在网上做完就行了,今年在刷题的时候突然想做一下记录以后做回顾,之后每天都在有道云笔记做点记录,现在既然开了公众号索性就增加这个专栏。每天一题每一题都吃透,希望看到自己成长的点点滴滴。我会用两种语言来解决所有问题,专科的时候主修java现在本科自学python,所以两种语言都做一个尝试。
No.1两数之和
原题:
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
示例:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]Java
首先想到遍历每个元素x,查找是否存在一个值与target-x 相等的目标元素.。
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] == target - nums[i]) {
return new int[] { i, j };
}
}
}
throw new IllegalArgumentException("No
two sum solution");
}
在写代码之前没有考虑时间复杂度只是想着运行结果正确就行,后来看了看解答原来还可以用哈希表,又用哈希表的方法对运行时间复杂度进行优化。
两遍哈希表
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement) &&
map.get(complement) != i) {
return new int[] {
i, map.get(complement) };
}
}
throw new IllegalArgumentException("No
two sum solution");
}
题目解答:
简单的实现使用了两次迭代。在第一次迭代中,我们将每个元素的值和它的索引添加到表中。然后,在第二次迭代中,我们将检查每个元素所对应的目标元素(target−nums[i]target - nums[i]target−nums[i])是否存在于表中。注意,该目标元素不能是 nums[i]nums[i]nums[i] 本身!
一遍哈希
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement)) {
return new int[] {
map.get(complement), i };
}
map.put(nums[i], i);
}
throw new IllegalArgumentException("No
two sum solution");
}
Python
用python写的时候思路跟java一样就是用一个嵌套循环把nums列表遍历两次。
class Solution:def twoSum(self,nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
n = len(nums)
for x in range(n):
for y in range(x+1,n):
if nums[y] == target - nums[x]:
return x,y
break
else:
continue
有了之前的经验这种方法实现以后就开始考虑有没有更加优化的方法,用一个for循环,直接在里面查询target-nums[x]是否存在于nums列表中
class Solution:def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
n = len(nums)
for x in range(n):
a = target - nums[x]
if a in nums:
y = nums.index(a)
if x == y:
continue
else:
return x, y
break
else:
continue
感觉这两种方法差不多最后一种方法是从小詹那看到的。通过创建字典,将nums里的值和序号对应起来,并创建另一个字典存储目标值(Target)-nums的值,通过判断该值是否在nums内进行判断并返回其对应索引值
class Solution:def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
num_dict = {nums[i]: i for i in range(len(nums))}
print(num_dict)
num_dict2 = {i: target - nums[i] for i in range(len(nums))}
print(num_dict2)
result = []
for i in range(len(nums)):
j = num_dict.get(num_dict2.get(i))
if (j is not None) and (j != i):
result = [i, j]
break
return result
这就是今天的LeetCode刷题,只是做个学习记录,水平有限,大家多多包含,如果小伙伴有更好的想法可以在留言区分享。